﻿/*!
 * Copyright (c), 上海沃恩信息科技有限公司.
 * All rights reserved.
 * Licensed under BSD (https://www.pittypat.work/bsd.html).
 */

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace Pittypat.Web
{
    /// <summary>
    /// 表示要发送给客户端的二进制数组。
    /// </summary>
    public sealed class ByteArray : IJson
    {
        private byte[] content;
        private string fileName;
        private string contentType;

        /// <summary>
        /// 使用要发送的二进制数组初始化 Binary 的新实例。
        /// </summary>
        /// <param name="content">字节数组。</param>
        /// <param name="fileName">文件名称。</param>
        /// <param name="contentType">内容类型，如果为 null 或空字符串，则根据文件名称自动获取。</param>
        public ByteArray(byte[] content, string fileName, string contentType = null)
        {
            if (content == null || content.Length == 0)
            {
                throw new ArgumentException("二进制内容不能是空的。");
            }

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentException("没有提供有效的文件名称。");
            }

            this.content = content ?? BinaryHelper.Empty;
            this.fileName = fileName;
            this.contentType = string.IsNullOrEmpty(contentType) ? Mime.Of(Path.GetExtension(fileName)) : contentType;
        }

        /// <summary>
        /// 获取二进制内容。
        /// </summary>
        public byte[] Content
        {
            get
            {
                return this.content;
            }
        }

        /// <summary>
        /// 获取文件名称。
        /// </summary>
        public string FileName
        {
            get
            {
                return this.fileName;
            }
        }

        /// <summary>
        /// 获取内容类型。
        /// </summary>
        public string ContentType
        {
            get
            {
                return this.contentType;
            }
        }

        void IJson.Write(TextWriter writer)
        {
            ((@binary)this.content).Write(writer);
        }

        // 通过 WebSocket 发送文件
        internal async Task<long> SendAsync(WebSocketAsyncProgress progress, int bufferSize = 0)
        {
            await progress.Socket.SendAsync(new ArraySegment<byte>(this.content), System.Net.WebSockets.WebSocketMessageType.Binary, true, progress.Token);
            return this.content.Length;
        }

        // 将文件作为响应内容附加到指定的响应消息
        internal void ToResponseContent(HttpResponseMessage response)
        {
            response.Content = new ByteArrayContent(this.content);
            response.Content.Headers.ContentType = new MediaTypeHeaderValue(this.contentType);
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = this.fileName
            };
        }
    }
}
